package com.carey.myblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carey.myblog.exception.NotFoundException;
import com.carey.myblog.pojo.Blog;
import com.carey.myblog.pojo.BlogTags;
import com.carey.myblog.pojo.Tag;
import com.carey.myblog.pojo.Type;
import com.carey.myblog.service.*;
import com.carey.myblog.mapper.BlogMapper;
import com.carey.myblog.util.MarkdownUtils;
import com.carey.myblog.vo.BlogQuery;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
* @author carey-
* @description 针对表【t_blog】的数据库操作Service实现
* @createDate 2022-05-25 22:09:39
*/
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog>
    implements BlogService{

    @Autowired
    private TypeService typeService;

    @Autowired
    private UserService userService;

    @Autowired
    private BlogTagsService blogTagsService;

    @Autowired
    private CommentService commentService;

    @Override
    public Blog getBlog(Long id) {
        Blog blog = baseMapper.selectById(id);
        return this.packBlog(blog);
    }

    @Transactional
    @Override
    public Blog getAndConvert(Long id) {
        Blog blog = this.packBlog(baseMapper.selectById(id));
        if(blog==null){
            throw new NotFoundException("该博客不存在");
        }
        String content=blog.getContent();
        blog.setContent(MarkdownUtils.markdownToHtmlExtensions(content));
        blog.setViews(blog.getViews()+1 );
        baseMapper.updateById(blog);
        return blog;
    }


    @Override
    public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(blog.getTitle())){
            wrapper.eq("title",blog.getTitle());
        }
        if (!StringUtils.isEmpty(blog.getTypeId())){
            wrapper.eq("type_id",blog.getTypeId());
        }
        if (blog.isRecommend()){
            wrapper.eq("recommend",blog.isRecommend());
        }
        wrapper.eq("published",true);
        wrapper.orderByDesc("update_time");

        int current = 0;
        if (pageable.getPageNumber() == 0){
            current =1;
        }else {
            current = pageable.getPageNumber();
        }
        int limit = 5;

        Page<Blog> page = new Page<>(current,limit);
        return this.packBlogPage(baseMapper.selectPage(page,wrapper));
    }

    @Override
    public Page<Blog> listBlog(Pageable pageable) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        int current = 0;
        if (pageable.getPageNumber() == 0){
            current =1;
        }else {
            current = pageable.getPageNumber();
        }
        int limit = 8;
        wrapper.orderByDesc("update_time");
        wrapper.eq("published",true);
        Page<Blog> page = new Page<>(current,limit);
        return this.packBlogPage(baseMapper.selectPage(page,wrapper));
    }

    @Override
    public Page<Blog> listBlogforadmin(Pageable pageable, BlogQuery blog) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(blog.getTitle())){
            wrapper.eq("title",blog.getTitle());
        }
        if (!StringUtils.isEmpty(blog.getTypeId())){
            wrapper.eq("type_id",blog.getTypeId());
        }
        if (blog.isDraft()){
            wrapper.eq("published",blog.isPublished());
        }
        if (blog.isRecommend()){
            wrapper.eq("recommend",blog.isRecommend());
        }
        wrapper.orderByDesc("update_time");

        int current = 0;
        if (pageable.getPageNumber() == 0){
            current =1;
        }else {
            current = pageable.getPageNumber();
        }
        int limit = 5;

        Page<Blog> page = new Page<>(current,limit);
        return this.packBlogPage(baseMapper.selectPage(page,wrapper));    }


    @Override
    public Page<Blog> listBlog(String query,Pageable pageable) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        int current = 0;
        if (pageable.getPageNumber() == 0){
            current =1;
        }else {
            current = pageable.getPageNumber();
        }
        int limit = 8;
        wrapper.orderByDesc("update_time");
        wrapper.like("title",query);
        wrapper.eq("published",true);
        Page<Blog> page = new Page<>(current,limit);
        return this.packBlogPage(baseMapper.selectPage(page,wrapper));
    }

    @Override
    public Page<Blog> listBlog(List<BlogTags> blogTags, Pageable pageable) {
        List<Long> ids = new ArrayList<>();
        blogTags.forEach(blogTag ->{
            ids.add(blogTag.getBlogsId());
        });
        List<Blog> blogs = baseMapper.selectBatchIds(ids);
        blogs.forEach(blog1 -> {
            this.packBlog(blog1);
        });
        int current = 0;
        if (pageable.getPageNumber() == 0){
            current =1;
        }else {
            current = pageable.getPageNumber();
        }
        int limit = 8;

        /*Page<Blog> page = new Page<>(current,limit);
        Page<Blog> blogPage = page.setRecords(blogs);
        System.out.println(blogs.size());
        System.out.println(blogPage.getSize());
        System.out.println(blogPage.getCurrent());
        System.out.println(blogPage.hasPrevious());
        System.out.println(blogPage.hasNext());
        System.out.println("total:"+blogPage.getTotal());*/


        // 分页代码片段
        // T表示对象实体 list是所要处理的列表数据
        Page<Blog> page = new Page<>(current,limit);
        // 当前页第一条数据在List中的位置
        int start = (current-1)*limit;
        // 当前页最后一条数据在List中的位置
        int end = (int)((start + page.getSize()) > blogs.size() ? blogs.size() : (page.getSize() * page.getCurrent()));
        //int end = (current*3)-1 >blogs.size() ? blogs.size() : ((current*3)-1);
        // 分隔列表 当前页存在数据时 设置
        page.setRecords(blogs.subList(start, end));

        page.setTotal(blogs.size());
        return page;//将list集合转换成page对象
    }

    @Override
    public Integer saveBlog(Blog blog) {
        if(blog.getId()==null){ //如果博客id为空则为新增，有id则为修改

            blog.setViews(0); //博客浏览量初始化

        }else {
            blog.setUpdateTime(new Date());
        }
        return baseMapper.insert(blog);
    }

    @Override
    public Integer updateBlog(Long id, Blog blog) {
        Blog blog1 = this.getBlog(id);
        if (blog1 == null){
            throw new NotFoundException("该博客不存在");
        }
        BeanUtils.copyProperties(blog,blog1);
        blog1.setUpdateTime(new Date());
        return baseMapper.updateById(blog1);
    }

    @Override
    public void deleteBlog(Long id) {
        baseMapper.deleteById(id);
        commentService.deleteByBlogId(id);
        blogTagsService.delete(id);
    }

    @Override
    public List<Blog> listRecommendBlogTop(int size) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("update_time");
        wrapper.eq("published",true);
        wrapper.last("limit"+"\t"+size);
        List<Blog> blogs = baseMapper.selectList(wrapper);
        return blogs;
    }

    @Override
    public Integer getCount(Long typeid) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.eq("type_id",typeid);
        wrapper.eq("published",true);
        return baseMapper.selectCount(wrapper);
    }

    @Override
    public Map<String, List<Blog>> archiveBlog() {
        Map<String, List<Blog>> map = new HashMap<>();
        List<String> years = baseMapper.selectyears();
        years.forEach(year -> {
            List<Blog> blogs = baseMapper.selectBlogByYear(year);
            map.put(year,blogs);
        });
        return map;
    }

    @Override
    public Integer countBlog() {
        return baseMapper.selectCount(null);
    }

    public Page<Blog> packBlogPage(Page<Blog> page){
        for (Blog blog : page.getRecords()) {
            Type type = typeService.getType(blog.getTypeId());
            blog.setType(type);
            blog.setUser(userService.getById(blog.getUserId()));
        }
        return page;

    }

    public Blog packBlog(Blog blog){
        Type type = typeService.getType(blog.getTypeId());
        blog.setType(type);
        blog.setUser(userService.getById(blog.getUserId()));
        List<Tag> list = blogTagsService.getTypeids(blog.getId());
        blog.setTags(list);
        return blog;
    }
}




